package com.masu.knows.faq.service.impl;


import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.masu.knows.commons.model.Tag;
import com.masu.knows.faq.mapper.TagMapper;
import com.masu.knows.faq.service.ITagService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 沈传尚
 * @since 2021-12-07
 */
@Service
public class TagServiceImpl extends ServiceImpl<TagMapper, Tag> implements ITagService {    //RedisTemplate源代码注入只注入了两个类型
    //RedisTemplate<String, String>
    //RedisTemplate<Object, Object>
    //如果使用@Autowired自动装配,因为泛型类型不匹配,所以会报错
    //但是@Resource是id 注入主要参数名称是redisTemplate就可以注入	//成功
    @Resource
    private RedisTemplate<String, List<Tag>> redisTemplate;

    @Autowired
    private TagMapper tagMapper;

    // 线程安全 并且是读操作无锁的ArrayList 写操作首先copy一个副本,
    private List<Tag> tags=new CopyOnWriteArrayList<>();

    private Map<String, Tag> tagsMap=new ConcurrentHashMap<>();

    @Override
    public List<Tag> getTags() {
        // 先从Redis中获得所有标签的集合
        List<Tag> tags = redisTemplate.opsForValue().get("tags");
        // 如果上面的获取失败(Redis中没有所有标签)
        // 那么就是第一次请求,需要数据库查询
        if (tags == null || tags.isEmpty()) {
            //连接数据库查询所有标签
            tags = tagMapper.selectList(null);
            //将全查出的标签保存到redis中
            redisTemplate.opsForValue().set("tags", tags);
            System.out.println("Redis已加载所有标签");
        }
        //千万别忘了返回tags
        return tags;
    }

    @Override
    public Map<String, Tag> tagsMap() {
        if (tags.isEmpty()){
            getTags();
        }
        return tagsMap;
    }
}
